/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * All Rights Researved.
 *
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 *
 * @author: jin Chen 
 * @date: Oct 16, 2003$
 * @version: 1.0
 */
package edu.psu.geovista.app.pcp.toolkits.collection;

import java.util.Arrays;
import java.util.Comparator;

public class ArrayUtils {

   
    public static void sortIgnoreCase(String [] a) {
        Arrays.sort(a,new StringIngoreCaseComparator());
    }
    public static class StringIngoreCaseComparator implements Comparator{
        public int compare(Object o1, Object o2) {
            String s1=(String) o1;
            String s2=(String) o2;
            return s1.compareToIgnoreCase(s2);
        }

    }
    /**
     * Sort data in ascending order, return sorted index.
     * Given an array data, assume the original index of element in the array is the id.
     * Then sort array based on the value of the element, return a array with the original ids in the same order as
     * that of the value in the sorted array
     * @param data
     * @return     ascendingly-sorted index. The sort is based on data values
     */
    public static int[] getIndexOfSortedValue(float[] data){
        if(data==null){
           new NullPointerException( ArrayUtils.class.getName() +".getIDsOfSortedValue() is passed a null argument");
        }
        DataWithID[] dwi=new DataWithID[data.length ];

        for (int i = 0; i < data.length; i++){
          dwi[i]=new DataWithID();
          dwi[i].id = i;
          dwi[i].value = data[i];
        }
        Arrays.sort(dwi);
        int[] ids=new int[dwi.length ];
        for (int i=0;i<ids.length ;i++){
            ids[i]=dwi[i].id ;
        }
        return ids;
    }
    /**
     * sort selected index in the same way as getIndexOfSortedValue(float[] values)
     * @param data
     * @param indexs  index of data selected from <values>
     * @return    ascendingly-sorted index of selected data. The sort is based on data values.
     */
    public static int[] getIndexOfSortedValue(float[] data, int[] indexs){
        for (int i=0;i<indexs.length ;i++){
            if(indexs[i]<0||indexs[i]>=data.length ){
               throw new IllegalArgumentException(ArrayUtils.class.getName() +"getIndexOfSortedValue() is passed invalid data");
            }
        }

        if(data==null){
           new NullPointerException( ArrayUtils.class.getName() +".getIDsOfSortedValue() is passed a null argument");
        }
        DataWithID[] dwi=new DataWithID[data.length ];

        for (int i = 0; i < data.length; i++){
          dwi[i]=new DataWithID();
          dwi[i].id = i;
          dwi[i].value = data[i];
        }
        Arrays.sort(dwi);
        Arrays.sort(indexs);
        int[] ids=new int[indexs.length ];
        int j=0;
        for (int i=0;i<dwi.length ;i++){
            int id=dwi[i].id ;
            if(Arrays.binarySearch(indexs,id)>=0 ){//id found in selected
                ids[j++]=id;
            }
        }
        return ids;
    }

    public static class DataWithID implements Comparable {
        int id;
        double value;

        //compared by value
        public int compareTo(Object o) {
            DataWithID e = (DataWithID) o;
            int val = 0;
            if (Double.isNaN(e.value)){
                if (Double.isNaN(this.value)){
                    return 0;
                } else {
                    return 1;
                }
            }//end if the other value is NaN

            if (Double.isNaN(this.value)){
                val = -1;//everything is bigger than NaN
            } else if (this.value < e.value) {
                val = -1;
            } else if (this.value > e.value) {
                val = 1;
            }

            return val;
        }
    }
    public static void main(String[] args) {
       System.out.println(" Test getIndexOfSortedValue(float[] data)");
       float[] v={1,9,7,2};
       int index[]= getIndexOfSortedValue(v);
        for (int i=0;i<index.length ;i++){
            System.out.print(" "+index[i]);
        }



        System.out.println(" Test getIndexOfSortedValue(float[] data)");
       float[] v2={1,9,7,2,0,3};
       int[] ind={1,5,4}; // data value are {9,0,3}
       int index2[]= getIndexOfSortedValue(v2 ,ind);
        for (int i=0;i<index2.length ;i++){
            System.out.print(" "+index2[i]);
        }


    }
}
